package com.sim.serialport.library.seria

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.util.Log
import com.drake.channel.sendEvent
import com.sim.serialport.library.R
import com.sim.serialport.library.seria.ext.bytesToHex
import com.sim.serialport.library.seria.ext.bytesToHex2
import com.sim.serialport.library.seria.ext.hexStringToByteArray
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.security.InvalidParameterException

class SerialManager() {
    var mSerialPort: SerialPort? = null
    var job: Job? = null
    var job2: Job? = null

    var receiveJobs: MutableList<Job?> = mutableListOf()

    fun initSerial(
        context: Activity,
        device: File,
        baudrate: Int,
        flags: Int,
        call: (bool: Boolean) -> Unit
    ) {
        try {
            mSerialPort = SerialPort().initSerial(device, baudrate, flags)
        } catch (e: SecurityException) {
            DisplayError(context, R.string.error_security)
        } catch (e: IOException) {
            DisplayError(context, R.string.error_unknown)
        } catch (e: InvalidParameterException) {
            DisplayError(context, R.string.error_configuration)
        } finally {
            call(mSerialPort?.inputStream != null)
        }
    }

    fun initSerialBack(device: File, baudrate: Int, flags: Int): Boolean {
        try {
            mSerialPort = null
            mSerialPort = SerialPort().initSerial(device, baudrate, flags)
        } catch (e: Exception) {
            Log.d("e----", "${e.message}")
        }
        return mSerialPort?.inputStream != null
    }

    private fun DisplayError(context: Activity, resourceId: Int) {
        val b = AlertDialog.Builder(context)
        b.setTitle("Error")
        b.setMessage(resourceId)
        b.setPositiveButton("OK") { dialog, which ->
            System.exit(0)
        }
        b.show()
    }

    fun sendData(mBuffer: ByteArray) {
        // 取消每个 Job 并将其置为 null
        for (i in receiveJobs.indices) {
            receiveJobs[i]?.cancel()  // 取消 Job
            receiveJobs[i] = null     // 将 Job 置为 null
        }
        // 清理完成后，你也可以选择清空列表以进一步释放内存
        receiveJobs.clear()



        job = CoroutineScope(Dispatchers.IO).launch {
            try {
                mSerialPort?.outputStream?.write(mBuffer) ?: run {
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun sendData(hex: String) {
        val mBuffer = hex.hexStringToByteArray()
        job = CoroutineScope(Dispatchers.IO).launch {
            try {
                mSerialPort?.outputStream?.write(mBuffer) ?: run {
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun receiveData() {
        job2 = CoroutineScope(Dispatchers.IO).launch {
            while (isActive) {
                try {
                    val inputStream = mSerialPort?.inputStream ?: kotlin.run {
                        return@launch
                    }
                    val buffer = ByteArrayOutputStream()
                    val tempBuffer = ByteArray(1024)
                    var size: Int
                    while (inputStream.available() > 0) {
                        size = inputStream.read(tempBuffer)
                        if (size > 0) {
                            buffer.write(tempBuffer, 0, size)
                        }
                    }
                    val hex = buffer.toByteArray().bytesToHex()
                    if (hex.isNotEmpty()) {
                        onDataReceived = buffer.toByteArray().bytesToHex()
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                delay(100)
            }
        }
    }

    fun addReceiveJob(job: Job) {
        receiveJobs.add(job)
    }

    fun clearReceiveJob() {
        // 取消每个 Job 并将其置为 null
        for (i in receiveJobs.indices) {
            receiveJobs[i]?.cancel()  // 取消 Job
            receiveJobs[i] = null     // 将 Job 置为 null
        }
        // 清理完成后，你也可以选择清空列表以进一步释放内存
        receiveJobs.clear()
    }

    var onDataReceived: String = ""
        get() {
            // 用过一次后，要还原
            val value = field
            resetReceiveData()
            return value
        }

    fun resetReceiveData() = run {
        onDataReceived = ""

//        clearReceiveJob()
    }
}